﻿////////////////////////////////////////////////////////////////////////
//                                                                    //
//                 Project: MediaElement Extensions                   //
//               Project URL: http://mext.codeplex.com                //
//                           GPL License v2                           //
//                                                                    //
//             Written by Geoffrey DANIEL { NeuroCypher }             //
//           Blog: http://blogs.developpeur.org/neurocypher           //
//                                                                    //
////////////////////////////////////////////////////////////////////////

using System;
using System.Windows;
using System.Windows.Controls;

namespace MediaElementExtensions.Controls.Managers
{

    public class MediaElementPropertyManager
    {

        #region Actions

        // MediaElement changed
        public Action _mediaElementChanged { get; private set; }

        // MediaElement events related actions
        public Action<object, RoutedEventArgs> _mediaElementCurrentStateChangedAction { get; private set; }
        public Action<object, RoutedEventArgs> _mediaElementDownloadProgressChangedAction { get; private set; }
        public Action<object, RoutedEventArgs> _mediaElementMediaEndedAction { get; private set; }
        public Action<object, ExceptionRoutedEventArgs> _mediaElementMediaFailedAction { get; private set; }
        public Action<object, RoutedEventArgs> _mediaElementMediaOpenedAction { get; private set; }

        #endregion

        #region Constructor

        public MediaElementPropertyManager(
            Action aMediaElementChanged,
            Action<object, RoutedEventArgs> aMediaElementCurrentStateChanged,
            Action<object, RoutedEventArgs> aMediaElementDownloadProgressChanged,
            Action<object, RoutedEventArgs> aMediaElementMediaEnded,
            Action<object, ExceptionRoutedEventArgs> aMediaElementMediaFailed,
            Action<object, RoutedEventArgs> aMediaElementMediaOpened)
        {

            _mediaElementChanged = aMediaElementChanged;

            _mediaElementCurrentStateChangedAction = aMediaElementCurrentStateChanged;
            _mediaElementDownloadProgressChangedAction = aMediaElementDownloadProgressChanged;
            _mediaElementMediaEndedAction = aMediaElementMediaEnded;
            _mediaElementMediaFailedAction = aMediaElementMediaFailed;
            _mediaElementMediaOpenedAction = aMediaElementMediaOpened;

        }

        #endregion

        #region MediaElement Property Changed

        public void MediaElementPropertyChanged(DependencyPropertyChangedEventArgs e)
        {

            var oldMediaElement = e.OldValue as MediaElement;
            var newMediaElement = e.NewValue as MediaElement;

            // unregister a potential old MediaElement
            if (oldMediaElement != null)
                UnregisterMediaElement(oldMediaElement);

            // register the new MediaElement
            if (newMediaElement != null)
                RegisterMediaElement(newMediaElement);

            // raise media element changed info
            if (_mediaElementChanged != null)
                _mediaElementChanged();

        }

        #endregion

        #region MediaElement Registering & Unregistering

        protected void RegisterMediaElement(MediaElement mediaElement)
        {

            if (mediaElement != null)
            {

                // MediaElement events' subscriptions
                if (_mediaElementCurrentStateChangedAction != null)
                    mediaElement.CurrentStateChanged += (s, e) => _mediaElementCurrentStateChangedAction(s, e);

                if (_mediaElementDownloadProgressChangedAction != null)
                    mediaElement.DownloadProgressChanged += (s, e) => _mediaElementDownloadProgressChangedAction(s, e);

                if (_mediaElementMediaEndedAction != null)
                    mediaElement.MediaEnded += (s, e) => _mediaElementMediaEndedAction(s, e);

                if (_mediaElementMediaFailedAction != null)
                    mediaElement.MediaFailed += (s, e) => _mediaElementMediaFailedAction(s, e);

                if (_mediaElementMediaOpenedAction != null)
                    mediaElement.MediaOpened += (s, e) => _mediaElementMediaOpenedAction(s, e);

            }

        }

        protected void UnregisterMediaElement(MediaElement mediaElement)
        {

            if (mediaElement != null)
            {

                // MediaElement events' unsubscriptions
                if (_mediaElementCurrentStateChangedAction != null)
                    mediaElement.CurrentStateChanged -= (s, e) => _mediaElementCurrentStateChangedAction(s, e);

                if (_mediaElementDownloadProgressChangedAction != null)
                    mediaElement.DownloadProgressChanged -= (s, e) => _mediaElementDownloadProgressChangedAction(s, e);

                if (_mediaElementMediaEndedAction != null)
                    mediaElement.MediaEnded -= (s, e) => _mediaElementMediaEndedAction(s, e);

                if (_mediaElementMediaFailedAction != null)
                    mediaElement.MediaFailed -= (s, e) => _mediaElementMediaFailedAction(s, e);

                if (_mediaElementMediaOpenedAction != null)
                    mediaElement.MediaOpened -= (s, e) => _mediaElementMediaOpenedAction(s, e);

            }

        }

        #endregion

    }

}
